package cn.zz.veggie.application.service;

import java.util.List;

import org.springframework.stereotype.Service;

import cn.zz.comm.types.result.R;
import cn.zz.comm.util.CollectorUtil;
import cn.zz.comm.util.NumberUtil;
import cn.zz.veggie.application.assembler.CategoryAssembler;
import cn.zz.veggie.application.helper.CategoryHelper;
import cn.zz.veggie.application.packer.CategoryPacker;
import cn.zz.veggie.model.domain.Category;
import cn.zz.veggie.model.query.CategoryQuery;
import cn.zz.veggie.persistence.repository.CategoryRepository;
import cn.zz.veggie.persistence.repository.ProductRepository;
import cn.zz.veggie.web.types.dto.mgmt.MgmtCategoryDto;
import cn.zz.veggie.web.types.dto.mgmt.MgmtCategoryQueryDto;
import cn.zz.veggie.web.types.vo.mgmt.MgmtCategoryVo;
import lombok.RequiredArgsConstructor;

/**
 * @author zhongq
 * @since 2024/4/25
 */
@Service
@RequiredArgsConstructor
public class CategoryAppService {

	private final CategoryRepository categoryRepository;
	private final ProductRepository productRepository;

	public List<MgmtCategoryVo> adminFinds(MgmtCategoryQueryDto dto) {
		CategoryQuery query = CategoryAssembler.buildAdminQuery(dto);
		List<Category> categories = categoryRepository.findByQuery(query);
		return CollectorUtil.bwl(categories, CategoryPacker::toMgmtVo);
	}

	public R<Void> adminSave(MgmtCategoryDto dto) {
		Integer parentId = NumberUtil.positiveOrZero(dto.getPid());
		Category parentCategory = categoryRepository.findById(parentId);
		CategoryHelper.checkParentExist(parentId, parentCategory);
		Category existCategory = categoryRepository.findByPidAndName(parentId, dto.getName());
		CategoryHelper.requireNotExist(dto.getId(), existCategory);
		Category category = CategoryAssembler.buildAdminSave(dto);
		categoryRepository.save(category);
		return R.ok();
	}

	public R<Void> adminDelete(Integer id) {
		Category category = categoryRepository.findById(id);
		CategoryHelper.requireNoNull(category, id);
		CategoryHelper.requireCanDelete(category);
		Category childCategory = categoryRepository.findOneByParentId(id);
		CategoryHelper.requireNoUsed(childCategory, id);
		categoryRepository.removeById(id);
		return R.ok();
	}

	public void adminChangeStatus(Integer id, Integer status) {
		Category category = categoryRepository.findById(id);
		CategoryHelper.requireNoNull(category, id);
		categoryRepository.save(CategoryAssembler.changeShow(category, status));
	}

}